home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / applications / wp / xvi.lha / Xvi_V1.0_Src / ex_cmds2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-04  |  7.3 KB  |  355 lines

  1. /* Copyright (c) 1990,1991,1992 Chris and John Downey */
  2. #ifndef lint
  3. static char *sccsid = "@(#)ex_cmds2.c    2.2 (Chris & John Downey) 8/3/92";
  4. #endif
  5.  
  6. /***
  7.  
  8. * program name:
  9.     xvi
  10. * function:
  11.     PD version of UNIX "vi" editor, with extensions.
  12. * module name:
  13.     ex_cmds2.c
  14. * module function:
  15.     Command functions for miscellaneous ex (colon) commands.
  16.     See ex_cmds1.c for file- and buffer-related colon commands.
  17. * history:
  18.     STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  19.     Originally by Tim Thompson (twitch!tjt)
  20.     Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  21.     Heavily modified by Chris & John Downey
  22.     Minor, Amiga specific modifications made by Dan Schmelzer.
  23.  
  24. ***/
  25.  
  26. #include "xvi.h"
  27.  
  28. #ifdef    MEGAMAX
  29. overlay "ex_cmds2"
  30. #endif
  31.  
  32. /*
  33.  * Run shell command.
  34.  *
  35.  * You might think it would be easier to do this as
  36.  *
  37.  *    sys_endv();
  38.  *    system(command);
  39.  *    sys_startv();
  40.  *    prompt("[Hit return to continue] ");
  41.  *    ...
  42.  *
  43.  * but the trouble is that, with some systems, sys_startv() can be
  44.  * used to swap display pages, which would mean that the user would
  45.  * never have time to see the output from the command. (This applies
  46.  * to some terminals, as well as machines with memory-mappped video;
  47.  * cmdtool windows on Sun workstations also do the same thing.)
  48.  *
  49.  * This means we have to display the prompt before calling
  50.  * sys_startv(), so we just use good old fputs(). (We're trying not to
  51.  * use printf()).
  52.  */
  53. /*ARGSUSED*/
  54. void
  55. do_shcmd(window, command)
  56. Xviwin    *window;
  57. char    *command;
  58. {
  59.     int    c;
  60.  
  61.     sys_endv();
  62.  
  63. #ifdef AMIGA
  64.     outstr("\r\n");
  65.     (void) call_system(command);
  66.     outstr("[Hit return to continue] ");
  67.     flush_output();
  68.     while ((c = inchar(0)) != '\n' && c != '\r' && c != EOF)
  69.     ;
  70. #else
  71.     (void) fputs(command, stdout);
  72.     (void) fputs("\r\n", stdout);
  73.     (void) fflush(stdout);
  74.     (void) call_system(command);
  75.     (void) fputs("[Hit return to continue] ", stdout);
  76.     (void) fflush(stdout);
  77.     while ((c = getc(stdin)) != '\n' && c != '\r' && c != EOF)
  78.     ;
  79. #endif
  80.  
  81.     sys_startv();
  82.     redraw_screen();
  83. }
  84.  
  85. void
  86. do_shell(window)
  87. Xviwin    *window;
  88. {
  89.     char    *sh = NULL;
  90.     int    sysret;
  91.  
  92.     sh = Ps(P_shell);
  93.     if (sh == NULL) {
  94.     show_error(window, "SHELL variable not set");
  95.     return;
  96.     }
  97.  
  98.     sys_endv();
  99.  
  100.     sysret = call_shell(sh);
  101.  
  102.     sys_startv();
  103.     redraw_screen();
  104.  
  105.     if (sysret != 0) {
  106. #ifdef STRERROR_AVAIL
  107.     show_error(window, "Can't execute %s [%s]", sh,
  108.             (errno > 0 ? strerror(errno) : "Unknown Error"));
  109. #else    /* strerror() not available */
  110.     show_error(window, "Can't execute %s", sh);
  111. #endif    /* strerror() not available */
  112.     }
  113. }
  114.  
  115. /*ARGSUSED*/
  116. void
  117. do_suspend(window)
  118. Xviwin    *window;
  119. {
  120.     if (State == NORMAL) {
  121. #    ifdef    SIGSTOP
  122.     extern    int    kill P((int, int));
  123.     extern    int    getpid P((void));
  124.  
  125.     sys_endv();
  126.  
  127.     (void) kill(getpid(), SIGSTOP);
  128.  
  129.     sys_startv();
  130.     redraw_screen();
  131.  
  132. #    else /* SIGSTOP */
  133.  
  134.     /*
  135.      * Can't suspend unless we're on a BSD UNIX system;
  136.      * just pretend by invoking a shell instead.
  137.      */
  138.     do_shell(window);
  139.  
  140. #    endif /* SIGSTOP */
  141.     }
  142. }
  143.  
  144. void
  145. do_equals(window, line)
  146. Xviwin    *window;
  147. Line    *line;
  148. {
  149.     if (line == NULL) {
  150.     /*
  151.      * Default position is ".".
  152.      */
  153.     line = window->w_cursor->p_line;
  154.     }
  155.  
  156.     show_message(window, "Line %ld", lineno(window->w_buffer, line));
  157. }
  158.  
  159. void
  160. do_help(window)
  161. Xviwin    *window;
  162. {
  163.     unsigned    savecho;
  164.  
  165.     savecho = echo;
  166.     echo &= ~(e_SCROLL | e_REPORT | e_SHOWINFO);
  167.     if (Ps(P_helpfile) != NULL && do_buffer(window, Ps(P_helpfile))) {
  168.     /*
  169.      * We use "curbuf" here because the new buffer will
  170.      * have been made the current one by do_buffer().
  171.      */
  172.     curbuf->b_flags |= FL_READONLY | FL_NOEDIT;
  173.     move_window_to_cursor(curwin);
  174.     show_file_info(curwin);
  175.     update_window(curwin);
  176.     }
  177.     echo = savecho;
  178. }
  179.  
  180. bool_t
  181. do_source(interactive, file)
  182. bool_t    interactive;
  183. char    *file;
  184. {
  185.     static char        cmdbuf[256];
  186.     FILE        *fp;
  187.     register int    c;
  188.     register char    *bufp;
  189.     bool_t        literal;
  190.  
  191.     fp = fopen(file, "r");
  192.     if (fp == NULL) {
  193.     if (interactive) {
  194.         show_error(curwin, "Can't open \"%s\"", file);
  195.     }
  196.     return(FALSE);
  197.     }
  198.  
  199.     bufp = cmdbuf;
  200.     literal = FALSE;
  201.     while ((c = getc(fp)) != EOF) {
  202.     if (!literal && (c == CTRL('V') || c == '\n')) {
  203.         switch (c) {
  204.         case CTRL('V'):
  205.         literal = TRUE;
  206.         break;
  207.  
  208.         case '\n':
  209.         if (kbdintr) {
  210.             imessage = TRUE;
  211.             break;
  212.         }
  213.         if (bufp > cmdbuf) {
  214.             *bufp = '\0';
  215.             do_colon(cmdbuf, FALSE);
  216.         }
  217.         bufp = cmdbuf;
  218.         break;
  219.         }
  220.     } else {
  221.         literal = FALSE;
  222.         if (bufp < &cmdbuf[sizeof(cmdbuf) - 1]) {
  223.         *bufp++ = c;
  224.         }
  225.     }
  226.     }
  227.     (void) fclose(fp);
  228.     return(TRUE);
  229. }
  230.  
  231. /*
  232.  * Change directory.
  233.  *
  234.  * With a NULL argument, change to the directory given by the HOME
  235.  * environment variable if it is defined; with an argument of "-",
  236.  * change back to the previous directory (like ksh).
  237.  *
  238.  * Return NULL pointer if OK, otherwise error message to say
  239.  * what went wrong.
  240.  */
  241. char *
  242. do_chdir(dir)
  243.     char    *dir;
  244. {
  245.     static char    *homedir = NULL;
  246.     static char    *prevdir = NULL;
  247.     char    *ret;
  248.     char    *curdir;
  249.  
  250.     if (dir == NULL && homedir == NULL &&
  251.                     (homedir = getenv("HOME")) == NULL) {
  252.     return("HOME environment variable not set");
  253.     }
  254.  
  255.     if (dir == NULL) {
  256.     dir = homedir;
  257.     } else if (*dir == '-' && dir[1] == '\0') {
  258.     if (prevdir == NULL) {
  259.         return("No previous directory");
  260.     } else {
  261.         dir = prevdir;
  262.     }
  263.     }
  264.  
  265.     curdir = malloc(MAXPATHLEN + 2);
  266.     if (curdir != NULL && getcwd(curdir, MAXPATHLEN + 2) == NULL) {
  267.     free(curdir);
  268.     curdir = NULL;
  269.     }
  270.     ret = (chdir(dir) == 0 ? NULL : "Invalid directory");
  271.     if (prevdir) {
  272.     free(prevdir);
  273.     prevdir = NULL;
  274.     }
  275.     if (curdir) {
  276.     prevdir = realloc(curdir, (unsigned) strlen(curdir) + 1);
  277.     }
  278.     return(ret);
  279. }
  280.  
  281. void
  282. do_cdmy(type, l1, l2, destline)
  283. int    type;            /* one of [cdmy] */
  284. Line    *l1, *l2;        /* start and end (inclusive) of range */
  285. Line    *destline;        /* destination line for copy/move */
  286. {
  287.     Posn    p1, p2;
  288.     Posn    destpos;
  289.  
  290.     p1.p_line = (l1 != NULL) ? l1 : curwin->w_cursor->p_line;
  291.     p2.p_line = (l2 != NULL) ? l2 : p1.p_line;
  292.     p1.p_index = p2.p_index = 0;
  293.  
  294.     if (type == 'c' || type == 'm') {
  295.     if (destline == NULL) {
  296.         show_error(curwin, "No destination specified");
  297.         return;
  298.     }
  299.     }
  300.  
  301.     /*
  302.      * Check that the destination is not inside
  303.      * the source range for "move" operations.
  304.      */
  305.     if (type == 'm') {
  306.     unsigned long    destlineno;
  307.  
  308.     destlineno = lineno(curbuf, destline);
  309.     if (destlineno >= lineno(curbuf, p1.p_line) &&
  310.                 destlineno <= lineno(curbuf, p2.p_line)) {
  311.         show_error(curwin, "Source conflicts with destination of move");
  312.         return;
  313.     }
  314.     }
  315.  
  316.     /*
  317.      * Yank the text to be copied.
  318.      */
  319.     if (do_yank(curbuf, &p1, &p2, FALSE, '@') == FALSE) {
  320.     show_error(curwin, "Not enough memory to yank text");
  321.     return;
  322.     }
  323.  
  324.     if (!start_command(curwin)) {
  325.     return;
  326.     }
  327.  
  328.     switch (type) {
  329.     case 'd':            /* delete */
  330.     case 'm':            /* move */
  331.     move_cursor(curwin, p1.p_line, 0);
  332.     repllines(curwin, p1.p_line, cntllines(p1.p_line, p2.p_line),
  333.                         (Line *) NULL);
  334.     update_buffer(curbuf);
  335.     cursupdate(curwin);
  336.     begin_line(curwin, TRUE);
  337.     }
  338.  
  339.     switch (type) {
  340.     case 'c':            /* copy */
  341.     case 'm':            /* move */
  342.     /*
  343.      * And put it back at the destination point.
  344.      */
  345.     destpos.p_line = destline;
  346.     destpos.p_index = 0;
  347.     do_put(curwin, &destpos, FORWARD, '@');
  348.  
  349.     update_buffer(curbuf);
  350.     cursupdate(curwin);
  351.     }
  352.  
  353.     end_command(curwin);
  354. }
  355.